package com.iwhalecloud.bss.kite.cucc.web.service.accept.handler.module;

import com.google.common.collect.Lists;
import com.iwhalecloud.bss.kite.client.vo.scene.ModuleVO;
import com.iwhalecloud.bss.kite.common.util.KiteListUtils;
import com.iwhalecloud.bss.kite.common.util.KiteMapUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.cucc.client.dto.pos.KitePosAttrDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.pos.KitePosDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.pos.KitePosGoodsFeeDTO;
import com.iwhalecloud.bss.kite.cucc.client.vo.scene.OptionalAdditionalOfferModuleVO;
import com.iwhalecloud.bss.kite.cucc.client.vo.scene.SceneNewOfferSeneVO;
import com.iwhalecloud.bss.kite.cucc.client.vo.scene.SceneProductModuleVO;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalKeyConsts;
import com.iwhalecloud.bss.kite.cucc.common.util.StrTools;
import com.iwhalecloud.bss.kite.cucc.dataservice.cache.ResaleOrderInfoCache;
import com.iwhalecloud.bss.kite.cucc.service.pay.PaymentService;
import com.iwhalecloud.bss.kite.cucc.service.util.ChangeTypeUtils;
import com.iwhalecloud.bss.kite.cucc.spec.impl.transfer.GoodsInfoTransfer;
import com.iwhalecloud.bss.kite.dataservice.cache.DcPublicCache;
import com.iwhalecloud.bss.kite.dataservice.cache.OfferCache;
import com.iwhalecloud.bss.kite.dataservice.cache.ProdFeeCache;
import com.iwhalecloud.bss.kite.dataservice.entity.DcPublic;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.Offer;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.OfferRelInfo;
import com.iwhalecloud.bss.kite.manager.api.IQuerySceneInstService;
import com.iwhalecloud.bss.kite.manager.enums.ActionType;
import com.iwhalecloud.bss.kite.manager.inst.KiteAttr;
import com.iwhalecloud.bss.kite.manager.inst.KiteOfferInst;
import com.iwhalecloud.bss.kite.manager.inst.KiteSceneInst;
import com.iwhalecloud.bss.kite.web.context.KiteWebContext;
import com.iwhalecloud.bss.kite.web.service.accept.bo.AcceptContext;
import com.iwhalecloud.bss.kite.web.service.accept.bo.SceneModule;
import com.iwhalecloud.bss.kite.web.service.accept.handler.module.AbstractModuleHandler;
import com.ztesoft.bss.base.staticdata.CoreDataOffer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @Description 返销页面 资费处理
 * @Author deng.gang
 * @Date 2022/1/20 5:29 下午
 */
@Service
public class ResaleOptionalAdditionalOfferModuleHandler extends AbstractModuleHandler {

    @Autowired
    IQuerySceneInstService querySceneInstService;

    @Autowired
    private OptionalAdditionalOfferModuleHandler handler;

    @Override
    public List<? extends ModuleVO> execute(AcceptContext context, SceneModule sceneModule) {
        Map<String, OptionalAdditionalOfferModuleVO> additionalOfferModuleVO = getOptionalAdditionalOfferModuleVO(context.getSceneVo().getSceneInstId());
        SceneProductModuleVO sceneFeeInfoVo = ((SceneNewOfferSeneVO) context.getSceneVo()).getSceneProductModuleVO();
        sceneFeeInfoVo.setAdditionalOffers(additionalOfferModuleVO);
        List<OptionalAdditionalOfferModuleVO> additionalOfferModuleVOList = new ArrayList<>();
        for (Map.Entry<String, OptionalAdditionalOfferModuleVO> entry : additionalOfferModuleVO.entrySet()) {
            additionalOfferModuleVOList.add(entry.getValue());
        }
        return additionalOfferModuleVOList;
    }

    private Map<String, OptionalAdditionalOfferModuleVO> getOptionalAdditionalOfferModuleVO(String sceneInstId) {
        Map<String, OptionalAdditionalOfferModuleVO> additionalOfferModuleVOMap = new HashMap<>();
        KiteSceneInst sceneInst = querySceneInstService.getSceneInst(sceneInstId);
        //所有的主套餐
        List<KiteOfferInst> offerInsts = Lists.newArrayList();
        offerInsts.addAll(querySceneInstService.listMainOfferInsts(sceneInstId));
        offerInsts.addAll(querySceneInstService.listPromotionOfferInsts(sceneInstId));

        // 五大双线 + 五大双线落地产品分类ID
        String[] cateIdArr = handler.getCateIdForDoubleLine();
        String[] zwyCate = handler.getCateIdForZWY();

        // 返销订单信息
        String resaleOrderId = querySceneInstService.getExtParameterValue(sceneInstId, "RESALE_ORDER_ID");
        KitePosDTO resalePosDTO = ResaleOrderInfoCache.get(resaleOrderId);
        // 获取到该订单新增的趸交资费
        List<KitePosGoodsFeeDTO> resaleFeeList = PaymentService.getOrderFee(resalePosDTO, ChangeTypeUtils.CHANGE_TYPE_A);

        for (KiteOfferInst kiteOfferInst : offerInsts) {
            String cateId = Optional.ofNullable(kiteOfferInst.getAttr("cateId")).map(KiteAttr::getDefaultValue).orElse("");
            // 主产品删除了，不加载
            if (KiteStringUtils.isEqual(kiteOfferInst.getActionType().name(), ActionType.D.name())) {
                continue;
            }
            //查询所有的可选包规格
            List<OfferRelInfo> offerRelInfoList = OfferCache.get(kiteOfferInst.getOfferId()).listAllOfferRels().stream().filter(offerRelInfo -> {
                return CoreDataOffer.OFF_0005_12.equals(offerRelInfo.getzOfferType());
            }).collect(Collectors.toList());
            if (KiteListUtils.isEmpty(offerRelInfoList)) {
                continue;
            }
            OptionalAdditionalOfferModuleVO additionalOfferModuleVO = new OptionalAdditionalOfferModuleVO();
            additionalOfferModuleVO.setAddButton(true);
            if (GoodsInfoTransfer.isAddRoleOffer(kiteOfferInst.getSpecId(), cateId)) {
                additionalOfferModuleVO.setAddFee(true);
            }
            additionalOfferModuleVO.setOfferName(OfferCache.get(kiteOfferInst.getOfferId()).getOfferName());
            additionalOfferModuleVO.setOfferInstId(kiteOfferInst.getOfferInstId());
            List<KiteOfferInst> additionalOfferInsts = querySceneInstService.listAdditionalOfferInstsFromOfferInst(KiteWebContext.getContext().getCustId(), kiteOfferInst.getOfferInstId());
            specialHandleFee(additionalOfferInsts, resaleFeeList);
            if (KiteListUtils.isNotEmpty(additionalOfferInsts)) {
                DealAdditionalOfferInst(sceneInstId, kiteOfferInst, additionalOfferModuleVO, additionalOfferInsts);
                if ((KiteStringUtils.equalsAny(cateId, cateIdArr) && KiteStringUtils.equalsAny(sceneInst.getServiceOfferId(), "1", "2826", "1014"))
                    || (KiteStringUtils.equalsAny(cateId, zwyCate) && KiteStringUtils.equalsAny(sceneInst.getServiceOfferId(), "1009"))
                    || handler.ifShowFeeStatistics(cateId, sceneInst.getServiceOfferId())) {
                    dealStatisticsTableData(sceneInstId, kiteOfferInst, additionalOfferModuleVO, additionalOfferInsts);
                }
            }
            additionalOfferModuleVOMap.put(kiteOfferInst.getOfferInstId(), additionalOfferModuleVO);
        }
        return additionalOfferModuleVOMap;
    }

    private void DealAdditionalOfferInst(String sceneInstId, KiteOfferInst kiteOfferInst, OptionalAdditionalOfferModuleVO additionalOfferModuleVO, List<KiteOfferInst> additionalOfferInsts) {
        //拼装表头
        List<Map> tableColList = new ArrayList();
        //描述字段组装
        List<String> feeDescribeFieldList = new ArrayList();
        //拼装表数据
        List<Map> tableValueList = new ArrayList();
        String cateId = kiteOfferInst.getAttrValue("cateId");
        handler.getTableHeader(tableColList, cateId, feeDescribeFieldList);
        //先按照生效时间排序
        handler.sortKitePosFeeList(additionalOfferInsts);
        //再按照销售品ID进行排序，行业5G资费只按照生效时间排序
        if (!KiteStringUtils.equals(cateId, "2000966")) {
            handler.sortOfferList(additionalOfferInsts);
        }
        additionalOfferInsts.forEach(feeOfferInst -> {
            Map tableValue = new HashMap();
            for (Map<String, String> tableCol : tableColList) {
                String key = tableCol.get("dataIndex");
                if (KiteStringUtils.isEqual(key, "ctrl")) {
                    continue;
                }
                if (KiteStringUtils.isEqual(key, "name")) {
                    tableValue.put(key, feeOfferInst.getOfferName());
                } else if (KiteStringUtils.isEqual(key, "feeDescribe")) {
                    StringBuffer feeDescribe = new StringBuffer();
                    for (String feeDescribeField : feeDescribeFieldList) {
                        if (!KiteStringUtils.isEqual(feeDescribeField, "name")) {
                            KiteAttr kiteAttr = feeOfferInst.getAttr(feeDescribeField);
                            if (Objects.nonNull(kiteAttr)) {
                                feeDescribe.append(kiteAttr.getCname()).append("=").append(getValue(kiteAttr)).append(";");
                            }
                        }
                    }
                    tableValue.put(key, feeDescribe.toString());
                } else if (KiteStringUtils.isEqual(key, "actionType")) {
                    tableValue.put(key, feeOfferInst.getActionType().name());
                } else {
                    KiteAttr kiteAttr = feeOfferInst.getAttr(key);
                    tableValue.put(key, getValue(kiteAttr));
                }
            }

            tableValue.put("offerInstId", feeOfferInst.getOfferInstId());
            Map<String, Object> offerMap = ProdFeeCache.get(feeOfferInst.getOfferId()).getOfferMap();
            String payType = KiteMapUtils.getString(offerMap, "payType");
            if (KiteMapUtils.isNotEmpty(offerMap)) {
                tableValue.put("payType", payType);
            }
            tableValue.put("modOfferInst", "false");
            tableValue.put("delOfferInst", "false");
            tableValue.put("cancelOfferInst", "false");
            // 生效模式
            KiteAttr effectiveMode = feeOfferInst.getAttr("200000174");
            if (Objects.nonNull(effectiveMode) && KiteStringUtils.isEqual(effectiveMode.getValue(), "110006909")) {
                tableValue.put("200000174", getValue(effectiveMode));
            }
            // 失效模式
            KiteAttr failureMode = feeOfferInst.getAttr("200001735");
            if (Objects.nonNull(failureMode) && KiteStringUtils.isEqual(failureMode.getValue(), "110006910")) {
                tableValue.put("200001735", getValue(failureMode));
            }
            tableValueList.add(tableValue);
        });
        Map tableFeeAttr = new HashMap();
        tableFeeAttr.put("tableCol", tableColList);
        tableFeeAttr.put("tableValue", tableValueList);
        additionalOfferModuleVO.setTableFeeAttr(tableFeeAttr);
    }

    private void dealStatisticsTableData(String sceneInstId, KiteOfferInst kiteOfferInst, OptionalAdditionalOfferModuleVO additionalOfferModuleVO, List<KiteOfferInst> additionalOfferInsts) {
        //拼装表头
        List<Map> tableColList = new ArrayList();
        //拼装表数据
        List<Map> tableValueList = new ArrayList();
        String catId = kiteOfferInst.getAttrValue("cateId");
        handler.getStatisticsTableHeader(tableColList, catId);
        //先按照生效时间排序
        handler.sortKitePosFeeList(additionalOfferInsts);
        //再按照销售品ID进行排序
        handler.sortOfferList(additionalOfferInsts);
        String countFee = "0";
        ArrayList<String> feeArray = new ArrayList<String>();
        additionalOfferInsts.forEach(feeOfferInst -> {
            // 作废的资费不计入总和
            if (ActionType.C.equals(feeOfferInst.getActionType())) {
                return;
            }
            if (!"".equals(getValue(feeOfferInst.getAttr("200001354"))) || !"".equals(getValue(feeOfferInst.getAttr("200000169")))) {
                Map tableValue = new HashMap();
                for (Map<String, String> tableCol : tableColList) {
                    String key = tableCol.get("dataIndex");
                    if (KiteStringUtils.isEqual(key, "ctrl")) {
                        continue;
                    }
                    if (KiteStringUtils.isEqual(key, "name")) {
                        tableValue.put(key, feeOfferInst.getOfferName());
                    } else if (KiteStringUtils.isEqual(key, "off")) {
                        if (KiteStringUtils.equalsAny(getValue(feeOfferInst.getAttr("200001354")), "", "0", "暂无价格")) {
                            tableValue.put(key, "N/A");
                        } else if (KiteStringUtils.equalsAny(getValue(feeOfferInst.getAttr("200000169")), "", "0")) {
                            tableValue.put(key, "N/A");
                        } else {
                            String discountRate = StrTools.numDivide(getValue(feeOfferInst.getAttr("200000169")), getValue(feeOfferInst.getAttr("200001354")), 2);
                            discountRate = StrTools.numMultiply(discountRate, "100");
                            tableValue.put(key, discountRate + "%");
                        }
                    } else {
                        KiteAttr kiteAttr = feeOfferInst.getAttr(key);
                        String fee = getValue(kiteAttr);
                        tableValue.put(key, fee);
                        if (KiteStringUtils.isEqual(key, "200000169") && !KiteStringUtils.isEqual(fee, "")) {
                            feeArray.add(getValue(kiteAttr));
                        }
                        // 存量资费标准资费统一展示成N/A
                        handler.handleStandardFee(tableValue, feeOfferInst, key);
                    }
                }
                tableValue.put("offerInstId", feeOfferInst.getOfferInstId());
                Map<String, Object> offerMap = ProdFeeCache.get(feeOfferInst.getOfferId()).getOfferMap();
                String payType = KiteMapUtils.getString(offerMap, "payType");
                if (KiteMapUtils.isNotEmpty(offerMap)) {
                    tableValue.put("payType", payType);
                }
                tableValue.put("modOfferInst", "false");
                tableValue.put("delOfferInst", "false");
                tableValue.put("cancelOfferInst", "false");
                // 生效模式
                KiteAttr effectiveMode = feeOfferInst.getAttr("200000174");
                if (Objects.nonNull(effectiveMode) && KiteStringUtils.isEqual(effectiveMode.getValue(), "110006909")) {
                    tableValue.put("200000174", getValue(effectiveMode));
                }

                // 失效模式
                KiteAttr failureMode = feeOfferInst.getAttr("200001735");
                if (Objects.nonNull(failureMode) && KiteStringUtils.isEqual(failureMode.getValue(), "110006910")) {
                    tableValue.put("200001735", getValue(failureMode));
                }
                tableValueList.add(tableValue);
            }
        });
        String Feeflag = "0";
        for (String value : feeArray) {
            countFee = StrTools.numAdd(countFee, value);
        }
        List<DcPublic> feeDcList = DcPublicCache.get("20211027001");
        if (KiteListUtils.isNotEmpty(feeDcList) && feeDcList.get(0).getPkey().contains(catId)) {
            BigDecimal countFeeBd = new BigDecimal(countFee);
            BigDecimal pcodeBd = new BigDecimal(feeDcList.get(0).getPcode());
            if (countFeeBd.compareTo(pcodeBd) == 1) {
                Feeflag = "1";
            }
        }
        Map tableStatisticsFeeAttr = new HashMap();
        tableStatisticsFeeAttr.put("tableCol", tableColList);
        tableStatisticsFeeAttr.put("tableValue", tableValueList);
        tableStatisticsFeeAttr.put("countFee", countFee);
        tableStatisticsFeeAttr.put("Feeflag", Feeflag);
        additionalOfferModuleVO.setTableStatisticsFeeAttr(tableStatisticsFeeAttr);
    }

    public String getValue(KiteAttr kiteAttr) {
        return handler.getValue(kiteAttr);
    }

    private static void specialHandleFee(List<KiteOfferInst> additionalOfferInsts, List<KitePosGoodsFeeDTO> resaleFeeList) {
        // 返销页面只展示该订单新增的趸交资费
        additionalOfferInsts.removeIf(additionalOfferInst -> {
            Map<String, Object> offerMap = Optional.ofNullable(ProdFeeCache.get(additionalOfferInst.getOfferId())).map(Offer::getOfferMap).orElse(null);
            // 只保留趸交资费
            if (!LocalKeyConsts.FEE_PAY_TYPE_ONE_OFF.equals(KiteMapUtils.getString(offerMap, "payType"))) {
                return true;
            }
            // 只展示该订单新增的趸交资费
            String feeInstanceId = getFeeInstanceId(additionalOfferInst);
            if (!resaleFeeList.stream().anyMatch(resaleFee -> KiteStringUtils.equals(feeInstanceId, getFeeInstanceId(resaleFee)))) {
                return true;
            }
            return false;
        });
    }

    private static String getFeeInstanceId(KiteOfferInst kiteOfferInst) {
        return Optional.ofNullable(kiteOfferInst.getAttr("210004688")).map(KiteAttr::getValue).orElse("");
    }

    private static String getFeeInstanceId(KitePosGoodsFeeDTO kitePosGoodsFeeDTO) {
        return Optional.ofNullable(kitePosGoodsFeeDTO.getAttrs().stream().filter(s -> KiteStringUtils.equals(s.getCode(), "210004688"))
            .findFirst().orElse(null)).map(KitePosAttrDTO::getValue).orElse("");
    }

}
